<template>
  <div class="document-list">
    <div class="list-header">
      <h3>📚 文档列表</h3>
      <div class="list-controls">
        <input 
          v-model="searchQuery" 
          @input="handleSearch"
          type="text" 
          placeholder="搜索文档..."
          class="search-input"
        />
        <button @click="refreshDocuments" class="refresh-btn" :disabled="loading">
          {{ loading ? '加载中...' : '🔄' }}
        </button>
      </div>
    </div>

    <div v-if="loading" class="loading">
      <p>⏳ 正在加载...</p>
    </div>

    <div v-else-if="filteredTree.length === 0" class="empty-state">
      <p>📭 暂无文档</p>
      <p v-if="currentSpaceId">此空间还没有文档，请创建一个文档</p>
      <p v-else>请先选择一个空间查看文档</p>
    </div>

    <div v-else class="tree-container">
      <DocumentTreeNode
        v-for="doc in filteredTree"
        :key="doc.id"
        :document="doc"
        :selected-id="selectedDocumentId"
        @select="onDocumentSelect"
        @edit="onDocumentEdit"
        @delete="confirmDeleteDocument"
        @move="handleDocumentMove"
      />
    </div>

    <div v-if="filteredTree.length > 0" class="list-footer">
      <p class="stats">共 {{ totalDocuments }} 个文档</p>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted, computed, watch } from 'vue'
import { useRoute } from 'vue-router'
import { documentApi } from '../services/api'
import type { Document } from '../types/document'
import DocumentTreeNode from './DocumentTreeNode.vue'
import { toast } from '../utils/message'

// Props
const props = defineProps<{
  spaceId: number | null
}>()

// 定义事件
const emit = defineEmits<{
  documentSelect: [document: Document]
  documentEdit: [document: Document]
  documentDelete: [id: number]
}>()

const documents = ref<Document[]>([])
const loading = ref(false)
const searchQuery = ref('')
const selectedDocumentId = ref<number | null>(null)

const route = useRoute()

// 计算属性
const currentSpaceId = computed(() => props.spaceId)

// 构建树形结构
const buildTree = (docs: Document[]): Document[] => {
  const docMap = new Map<number, Document>()
  const roots: Document[] = []

  // 创建文档映射
  docs.forEach(doc => {
    docMap.set(doc.id, { ...doc, children: [] })
  })

  // 构建树形结构
  docs.forEach(doc => {
    const docWithChildren = docMap.get(doc.id)!
    if (doc.parentId && docMap.has(doc.parentId)) {
      const parent = docMap.get(doc.parentId)!
      if (!parent.children) parent.children = []
      parent.children.push(docWithChildren)
    } else {
      roots.push(docWithChildren)
    }
  })

  return roots
}

// 过滤树形结构
const filterTree = (tree: Document[], query: string): Document[] => {
  if (!query.trim()) return tree
  
  const queryLower = query.toLowerCase()
  
  const filter = (node: Document): Document | null => {
    const matches = node.name.toLowerCase().includes(queryLower) || 
                   node.content.toLowerCase().includes(queryLower)
    
    const filteredChildren = (node.children || [])
      .map(child => filter(child))
      .filter(Boolean) as Document[]
    
    if (matches || filteredChildren.length > 0) {
      return { ...node, children: filteredChildren }
    }
    
    return null
  }
  
  return tree.map(root => filter(root)).filter(Boolean) as Document[]
}

const documentTree = computed(() => buildTree(documents.value))
const filteredTree = computed(() => filterTree(documentTree.value, searchQuery.value))
const totalDocuments = computed(() => documents.value.length)

// 获取文档列表
const fetchDocuments = async (): Promise<void> => {
  if (!props.spaceId) {
    documents.value = []
    return
  }

  try {
    loading.value = true
    documents.value = await documentApi.getByNamespace(props.spaceId)
    
    // 如果有文档且没有选中文档，且路由中也没有指定文档ID，才选择第一个
    if (!selectedDocumentId.value && documents.value.length > 0 && !route.params.id) {
      const firstDoc = documents.value[0]
      selectedDocumentId.value = firstDoc.id
      emit('documentSelect', firstDoc)
    }
  } catch (err: any) {
    console.error('获取文档列表失败:', err)
    
    let errorMessage = ''
    if (err.code === 'ECONNREFUSED' || err.code === 'ERR_NETWORK') {
      errorMessage = '无法连接到服务器，请检查网络连接'
    } else if (err.response?.status === 404) {
      errorMessage = 'API接口未找到，请检查服务器配置'
    } else if (err.response?.status >= 500) {
      errorMessage = '服务器错误，请稍后重试'
    } else {
      errorMessage = `获取文档列表失败: ${err.response?.data?.message || err.message}`
    }
    
    // 使用toast显示错误，而不是在页面中显示
    toast.error(errorMessage)
  } finally {
    loading.value = false
  }
}

const refreshDocuments = (): void => {
  fetchDocuments()
}

const handleSearch = (): void => {
  // 实时过滤，无需调用API
}

const onDocumentSelect = async (document: Document): Promise<void> => {
  selectedDocumentId.value = document.id
  
  // 如果文档没有content，需要获取详细信息
  if (!document.content) {
    try {
      const detailDoc = await documentApi.getById(document.id)
      const fullDocument: Document = {
        ...document,
        content: detailDoc.content,
        sortNo: detailDoc.sortNo,
        createdTime: detailDoc.createdTime,
        updatedTime: detailDoc.updatedTime
      }
      emit('documentSelect', fullDocument)
    } catch (error) {
      console.error('获取文档详情失败:', error)
      emit('documentSelect', document)
    }
  } else {
    emit('documentSelect', document)
  }
}

const onDocumentEdit = (document: Document): void => {
  emit('documentEdit', document)
}

const confirmDeleteDocument = async (id: number): Promise<void> => {
  const confirmed = await toast.confirm(
    '确定要删除这个文档吗？此操作不可撤销。',
    {
      title: '删除文档',
      confirmButtonText: '删除',
      cancelButtonText: '取消'
    }
  )
  
  if (confirmed) {
    emit('documentDelete', id)
  }
}

const handleDocumentMove = async (moveData: { sourceId: number; targetId: number | null; insertPosition: 'before' | 'after' | 'inside' }) => {
  // TODO: 实现拖拽移动功能
  console.log('文档移动:', moveData)
}

// 监听空间ID变化
watch(() => props.spaceId, (newSpaceId, oldSpaceId) => {
  // 只有当空间真正切换时才清空选中文档，如果是初始化或相同空间则保留
  if (oldSpaceId !== undefined && newSpaceId !== oldSpaceId) {
    // 检查当前路由是否有文档ID，如果有则保留选中状态
    if (!route.params.id) {
      selectedDocumentId.value = null
    }
  }
  
  if (newSpaceId) {
    fetchDocuments()
  }
}, { immediate: false })  // 改为 false，避免初始化时就触发

// 监听路由变化，同步选中的文档ID
watch(() => route.params.id, (newId) => {
  if (newId && typeof newId === 'string') {
    selectedDocumentId.value = parseInt(newId)
  } else if (!newId) {
    selectedDocumentId.value = null
  }
})

// 组件挂载时的初始化
onMounted(() => {
  // 设置路由中的文档ID
  if (route.params.id && typeof route.params.id === 'string') {
    selectedDocumentId.value = parseInt(route.params.id)
  }
  
  // 如果有空间ID，获取文档列表
  if (props.spaceId) {
    fetchDocuments()
  }
})

// 暴露方法供父组件调用
defineExpose({
  refreshDocuments,
  selectDocument: (docId: number) => {
    selectedDocumentId.value = docId
  }
})
</script>

<style scoped>
.document-list {
  flex: 1;
  display: flex;
  flex-direction: column;
  background: white;
  min-height: 0;
}

.list-header {
  padding: 1rem;
  border-bottom: 1px solid #e1e1e1;
  display: flex;
  justify-content: space-between;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.5rem;
}

.list-header h3 {
  margin: 0;
  color: #42b883;
  font-size: 1.1rem;
}

.list-controls {
  display: flex;
  gap: 0.5rem;
  align-items: center;
}

.search-input {
  padding: 0.4rem 0.8rem;
  border: 1px solid #e1e1e1;
  border-radius: 4px;
  font-size: 0.9rem;
  width: 200px;
}

.search-input:focus {
  outline: none;
  border-color: #42b883;
}

.refresh-btn {
  padding: 0.4rem 0.8rem;
  background: #42b883;
  color: white;
  border: none;
  border-radius: 4px;
  cursor: pointer;
  font-size: 0.85rem;
  transition: background 0.3s;
}

.refresh-btn:hover:not(:disabled) {
  background: #369870;
}

.refresh-btn:disabled {
  opacity: 0.6;
  cursor: not-allowed;
}

.loading, .empty-state {
  padding: 2rem 1rem;
  text-align: center;
  color: #666;
}

.tree-container {
  flex: 1;
  overflow-y: auto;
  padding: 0.5rem 0;
}

.list-footer {
  padding: 1rem;
  border-top: 1px solid #e1e1e1;
  background: #f9f9f9;
}

.stats {
  margin: 0;
  font-size: 0.8rem;
  color: #666;
}

@media (max-width: 768px) {
  .list-header {
    flex-direction: column;
    align-items: stretch;
  }
  
  .list-controls {
    justify-content: space-between;
  }
  
  .search-input {
    width: auto;
    flex: 1;
  }
}
</style>